{
 "nbformat": 4,
 "nbformat_minor": 0,
 "metadata": {
  "colab": {
   "name": "handwritten_digit_recognition_CPU.ipynb",
   "version": "0.3.2",
   "provenance": [],
   "collapsed_sections": []
  },
  "kernelspec": {
   "name": "python3",
   "language": "python",
   "display_name": "Python 3 (ipykernel)"
  }
 },
 "cells": [
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision.transforms as transforms\n",
    "from PIL import Image\n",
    "import matplotlib.pyplot as plt\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-26T14:48:02.582764100Z",
     "start_time": "2024-11-26T14:48:02.570094Z"
    }
   },
   "execution_count": 21
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "ename": "UnpicklingError",
     "evalue": "Weights only load failed. This file can still be loaded, to do so you have two options \n\t(1) Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.\n\t(2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message.\n\tWeightsUnpickler error: Unsupported global: GLOBAL builtins.set was not an allowed global by default. Please use `torch.serialization.add_safe_globals([set])` to allowlist this global if you trust this class/function.\n\nCheck the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html.",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mUnpicklingError\u001B[0m                           Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[26], line 7\u001B[0m\n\u001B[0;32m      5\u001B[0m torch\u001B[38;5;241m.\u001B[39mserialization\u001B[38;5;241m.\u001B[39madd_safe_globals([Net])\n\u001B[0;32m      6\u001B[0m \u001B[38;5;66;03m# 加载训练好的模型\u001B[39;00m\n\u001B[1;32m----> 7\u001B[0m model \u001B[38;5;241m=\u001B[39m \u001B[43mtorch\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mload\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43m./my_mnist_model.pt\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mweights_only\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mTrue\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[0;32m      8\u001B[0m model\u001B[38;5;241m.\u001B[39meval()  \u001B[38;5;66;03m# 设置模型为评估模式\u001B[39;00m\n\u001B[0;32m      9\u001B[0m \u001B[38;5;66;03m# 定义图像预处理\u001B[39;00m\n",
      "File \u001B[1;32mD:\\Documents\\Tool\\anaconda3\\envs\\Pytorch\\lib\\site-packages\\torch\\serialization.py:1096\u001B[0m, in \u001B[0;36mload\u001B[1;34m(f, map_location, pickle_module, weights_only, mmap, **pickle_load_args)\u001B[0m\n\u001B[0;32m   1090\u001B[0m                 \u001B[38;5;28;01mreturn\u001B[39;00m _load(opened_zipfile,\n\u001B[0;32m   1091\u001B[0m                              map_location,\n\u001B[0;32m   1092\u001B[0m                              _weights_only_unpickler,\n\u001B[0;32m   1093\u001B[0m                              overall_storage\u001B[38;5;241m=\u001B[39moverall_storage,\n\u001B[0;32m   1094\u001B[0m                              \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mpickle_load_args)\n\u001B[0;32m   1095\u001B[0m             \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mRuntimeError\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m-> 1096\u001B[0m                 \u001B[38;5;28;01mraise\u001B[39;00m pickle\u001B[38;5;241m.\u001B[39mUnpicklingError(_get_wo_message(\u001B[38;5;28mstr\u001B[39m(e))) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m   1097\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m _load(\n\u001B[0;32m   1098\u001B[0m             opened_zipfile,\n\u001B[0;32m   1099\u001B[0m             map_location,\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m   1102\u001B[0m             \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mpickle_load_args,\n\u001B[0;32m   1103\u001B[0m         )\n\u001B[0;32m   1104\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m mmap:\n",
      "\u001B[1;31mUnpicklingError\u001B[0m: Weights only load failed. This file can still be loaded, to do so you have two options \n\t(1) Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.\n\t(2) Alternatively, to load with `weights_only=True` please check the recommended steps in the following error message.\n\tWeightsUnpickler error: Unsupported global: GLOBAL builtins.set was not an allowed global by default. Please use `torch.serialization.add_safe_globals([set])` to allowlist this global if you trust this class/function.\n\nCheck the documentation of torch.load to learn more about types accepted by default with weights_only https://pytorch.org/docs/stable/generated/torch.load.html."
     ]
    }
   ],
   "source": [
    "\n",
    "# 加载训练好的模型（模型架构需要与训练时一致）\n",
    "model= torch.load('./my_mnist_model.pt')\n",
    "model.eval()  # 设置模型为评估模式\n",
    "\n",
    "# 定义图像预处理\n",
    "transform = transforms.Compose([\n",
    "    transforms.Resize((28, 28)),  # 调整大小为28x28\n",
    "    transforms.ToTensor(),\n",
    "    transforms.Normalize((0.5,), (0.5,))\n",
    "])\n",
    "\n",
    "# 加载图片并进行预处理\n",
    "def load_image(image_path):\n",
    "    image = Image.open(image_path).convert('L')  # 转为灰度图\n",
    "    image = transform(image)\n",
    "    image = image.unsqueeze(0)  # 增加一个维度，用于 batch 处理 (1, 1, 28, 28)\n",
    "    return image\n",
    "\n",
    "# 识别图片\n",
    "def predict(image_path):\n",
    "    image = load_image(image_path)\n",
    "    with torch.no_grad():  # 不需要计算梯度\n",
    "        output = model(image)\n",
    "        _, predicted = torch.max(output, 1)\n",
    "    return predicted.item()\n",
    "\n",
    "# 例子：识别一张图片\n",
    "image_path = './test/img.png'  # 替换为你的图片路径\n",
    "predicted_label = predict(image_path)\n",
    "print(f'Predicted Label: {predicted_label}')\n",
    "\n",
    "# 可视化预测结果\n",
    "image = Image.open(image_path).convert('L')\n",
    "plt.imshow(image, cmap='gray_r')\n",
    "plt.title(f'Predicted: {predicted_label}')\n",
    "plt.axis('off')\n",
    "plt.show()\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-26T14:50:42.400002600Z",
     "start_time": "2024-11-26T14:50:42.375995300Z"
    }
   },
   "execution_count": 26
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ]
}
